package com.platform.event.core.impl;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;

import com.alibaba.fastjson.JSONObject;
import com.platform.event.core.EventHandleHelper;
import com.platform.event.core.EventService;
import com.platform.event.core.contants.EventConstants;
import com.platform.event.core.enums.EventStatusEnum;
import com.platform.event.core.mapper.EventHistoryMapper;
import com.platform.event.core.mapper.EventMapper;
import com.platform.event.core.model.BaseEvent;
import com.platform.event.core.model.EventResult;

public class EventServiceImpl implements EventService {
//	@Autowired
	private EventMapper eventMapper;
//	@Autowired
	private EventHistoryMapper eventHistoryMapper;
	@Autowired
	private Environment environment;
	@Autowired
	private EventHandleHelper eventHandlerHelper;
	Logger logger = LoggerFactory.getLogger(EventServiceImpl.class);

	@Override
	public EventResult saveEvent(BaseEvent event) {
		event.setRetryTime(0);
		event.setGmtCreate(new Date());
		event.setEventStatus(EventStatusEnum.WAIT_HANDLE.name());
		event.setGmtModify(new Date());
		eventMapper.insertSelective(event);
		return new EventResult(true);
	}

	@Override
	public List<BaseEvent> searchHandleEvent(String status) {
		// TODO Auto-generated method stub
		return eventMapper.selectEventByStatus(status);
	}

	@Override
	public BaseEvent findOneForUpdate(Integer eventProcessId) {
		// TODO Auto-generated method stub
		return eventMapper.selectByPrimaryKey(eventProcessId);
	}

	@Override
	public void handleCallBack(BaseEvent event, EventResult result) {
		if (event == null) {
			return;
		}
		event.setGmtModify(new Date());
		// 调用正确回调
		if (result.isSuccess()) {
			event.setException(result.getMessage());
			event.setResult(JSONObject.toJSONString(result));
			event.setEventStatus(EventStatusEnum.HANDLE_SUCCESS.name());
			eventMapper.updateByPrimaryKeySelective(event);
		} else if (!result.isSuccess() && event.getRetryTime() < EventConstants.MAX_RETRY_TIME) {
			event.setRetryTime(event.getRetryTime() + 1);
			event.setException(result.getMessage());
			event.setResult(JSONObject.toJSONString(result));
			event.setEventStatus(EventStatusEnum.WAIT_RETRY.name());
			eventMapper.updateByPrimaryKeySelective(event);
		} else {
			event.setException(result.getMessage());
			event.setEventStatus(EventStatusEnum.HANDLE_FAILED.name());
			event.setResult(JSONObject.toJSONString(result));
			eventMapper.updateByPrimaryKeySelective(event);
		}
	}

	@Override
	public List<BaseEvent> searchWaitDeleteEvent() {
		return eventMapper.selectWaitDeleteEvent();
	}

	@Override
	public void removeEventToHistory(BaseEvent event) {
		eventMapper.deleteByPrimaryKey(event.getId());
		eventHistoryMapper.insertByBaseEvent(event);
	}

	@Override
	public void setEventDescription(BaseEvent event) {

		String info = System.getProperty("os.name");
		String port = environment.getProperty("server.port");
		try {
			String address = InetAddress.getLocalHost().getHostAddress();
			String hostName = InetAddress.getLocalHost().getHostName();
			JSONObject description = new JSONObject();
			description.put("address", address);
			description.put("hostName", hostName);
			description.put("os", info);
			description.put("port", port);
			event.setDescription(description.toJSONString());
		} catch (UnknownHostException e) {
			JSONObject description = new JSONObject();
			description.put("address", "unkonw");
			description.put("hostName", "unkonw");
			description.put("os", info);
			description.put("port", port);
			event.setDescription(description.toJSONString());
		}
	}

	
	@Override
	public void handleEventProcess(BaseEvent event) {
		logger.info(String.format("handle event process, id: %d, event category: %s ", event.getId(),
				event.getEventName()));
		eventHandlerHelper.handle(event, this);

	}

	@Override
	public void handleDeleteEventProcess(BaseEvent event) {
		removeEventToHistory(event);
	}

}
